%{
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <malloc.h>
 #ifndef YYSTYPE
 #define YYSTYPE double
 #endif
 int yylex ();
 extern int yyparse();
 FILE* yyin ;
 void yyerror(const char* s );


struct id_struct
{
	char id_name[50];
	double id_value;
}id;
%}


%token ID
%token NUMBER
%token EQUAL
%token ADD
%token SUB
%token MUL
%token DIV
%left ADD SUB
%left MUL DIV
%right UMINUS

%%

lines 	:	lines expr ';' { printf("%f\n", $2); }
	|	lines ';'
	|
	;

expr	:	expr  ADD expr	{$$=$1+$3;} 
	|	expr  SUB expr	{$$=$1-$3;}
	|	expr  MUL expr	{$$=$1*$3;}
	|	expr  DIV expr	{ if($3==0.0)
					yyerror("divide by zero!");
				else 
					$$=$1/$3;} 
	|	'(' expr ')'		{$$=$2;}
	|	SUB expr %prec UMINUS	{$$=-$2;}
	|	ID	{$$=id.id_value;}
	|	ID EQUAL expr {	$$=$3;
				id.id_value=$3;}
	|	NUMBER{$$=$1;}
	;


%%

// programs section
int yylex()
{
// place your token retrieving code here
int t;
while(1) {
	t=getchar();
	if(t==' '|| t=='\t' || t=='\n')
        {//do nothing
	}
	else if( isdigit(t))
	{	yylval=0;
		while (isdigit(t))
		{
			yylval=yylval*10+t-'0';
			t=getchar();
		}
	ungetc(t,stdin);
	return NUMBER;
	}
	else if((t>='a'&&t<='z')||(t>='A'&&t<='Z')||(t=='_'))
	{	int ti=0;
		while((t>='a'&&t<='z')||(t>='A'&&t<='Z')||(t=='_')||(t>='0'&&t<='9'))
		{	id.id_name[ti]=t;
			ti++;
			t=getchar();
		}
		id.id_name[ti]='\0';
		ungetc(t,stdin);
		return ID;
	}
	else if(t=='+')
		return ADD;
	else if(t=='-')
		return SUB;
	else if(t=='*')
		return MUL;
	else if(t=='/')
		return DIV;
	else if(t=='=')
		return EQUAL;
	else
	{	return t;	}
}
}

int main(void)
{
   yyin = stdin ;
   do {
   yyparse();
} while (! feof (yyin));
 return 0;
}
 void yyerror(const char*s) {
 fprintf (stderr , "Parse error : %s\n", s );
 exit (1);
}
